package fraction;

/**
 * Class MixedFraction
 * 
 * @author lorenz gorse
 */
public class MixedFraction extends Fraction {
    /**
     * Creates a new mixed fraction
     *
     * @param number the integer part of the fraction
     * @param numerator the numerator
     * @param denominator the denominator
     */
	public MixedFraction(int number, int numerator, int denominator) {
		super(number * denominator + numerator, denominator);
    }

    /**
     * Creates a new mixed fraction without an integer part
     *
     * @param numerator the numerator
     * @param denominator the denominator
     */
    public MixedFraction(int numerator, int denominator) {
        super(numerator, denominator);
    }

    /**
     * Creates a new MixedFraction from an existing Fraction
     *
     * @param f the simple fraction the mixed fraction is to be created from
     */
    public MixedFraction(Fraction f) {
        super(f.getNumerator(), f.getDenominator());
    }

    /**
     * Adds two mixed fractions mf1 and mf2
     *
     * @param mf1 the first mixed fraction
     * @param mf2 the second mixed fraction
     * @return the sum of mf1 and mf2 as a mixed fraction
     */
    public static MixedFraction add(MixedFraction mf1, MixedFraction mf2) {
        // Convert the mixed fractions mf1 and mf2 into simple fractions
        Fraction f1 = new Fraction(mf1);
        Fraction f2 = new Fraction(mf2);

        // Add these simple fractions with the Fraction class
        Fraction f = Fraction.add(f1, f2);

        // Return a mixed fraction that is equivalent to f
        return new MixedFraction(f);
    }

    /**
     * Subtracts two mixed fractions mf1 and mf2
     *
     * @param mf1 the first mixed fraction
     * @param mf2 the second mixed fraction
     * @return the difference between mf1 and mf2 as a mixed fraction
     */
    public static MixedFraction subtract(MixedFraction mf1, MixedFraction mf2) {
        // Convert the mixed fractions mf1 and mf2 into simple fractions
        Fraction f1 = new Fraction(mf1);
        Fraction f2 = new Fraction(mf2);

        // Subtract these simple fractions with the Fraction class
        Fraction f = Fraction.subtract(f1, f2);

        // Return a mixed fraction that is equivalent to f
        return new MixedFraction(f.getNumerator(), f.getDenominator());
    }

    /**
     * Multiplicates two mixed fractions f1 and f2
     *
     * @param mf1 the first mixed fraction
     * @param mf2 the second mixed fraction
     * @return the product of mf1 and mf2 as a mixed fraction
     */
    public static MixedFraction multiplicate(MixedFraction mf1, MixedFraction mf2) {
        // Convert the mixed fractions mf1 and mf2 into simple fractions
        Fraction f1 = new Fraction(mf1);
        Fraction f2 = new Fraction(mf2);

        // Multiplicate these simple fractions with the Fraction class
        Fraction f = Fraction.multiplicate(f1, f2);

        // Return a mixed fraction that is equivalent to f
        return new MixedFraction(f.getNumerator(), f.getDenominator());
    }

    /**
     * Divides two mixed fractions f1 and f2
     *
     * @param mf1 the first mixed fraction
     * @param mf2 the second mixed fraction
     * @return the quotient of mf1 and mf2 as a mixed fraction
     */
    public static MixedFraction divide(MixedFraction mf1, MixedFraction mf2) {
        // Convert the mixed fractions mf1 and mf2 into simple fractions
        Fraction f1 = new Fraction(mf1);
        Fraction f2 = new Fraction(mf2);

        // Divide these simple fractions with the Fraction class
        Fraction f = Fraction.divide(f1, f2);

        // Return a mixed fraction that is equivalent to f
        return new MixedFraction(f.getNumerator(), f.getDenominator());
    }

    /**
     * Converts the fraction into a string
     *
     * @return the fraction as a string
     */
    @Override
    public String toString() {
        // The biggest integer that satisfies the condition (number * denominator <= numerator)
        int number = (int) Math.floor(numerator / denominator);
        // The real numerator is the numerator without the integer part of the fraction
        int realNumerator = this.numerator - (number * this.denominator);
        // The real denominator is equivalent to the original denominator
        int realDenominator = this.denominator;

        if(realNumerator == 0) {
            // If the numerator is zero, only the integer part is interesting
            return Integer.toString(number);
        } else if(number == 0) {
            // If the number is zero, only the fraction is interesting
            return realNumerator + "/" + realDenominator;
        } else {
            // Otherwise, both are interesting
            return number + " " + realNumerator + "/" + realDenominator;
        }
    }
}
